use axum::Json;
use serde_json::{json, Value};
use tokio::{fs::{self, File}, io::{AsyncReadExt, AsyncWriteExt}};

use crate::code;
use super::utils::{ exist, exist_rel, get_rel_path };

pub async fn create_dir_all_rel(path:&str) -> Result<(), Json<Value>>{
    let path = get_rel_path(path);
    if exist_rel(&path)?{
        Ok(())
    }else {
        match fs::create_dir_all(path).await {
            Ok(_) => Ok(()),
            Err(e) => Err( code::sys_(super::error::msg(e)))
        }
    }
}
pub async fn create_dir_all(path:&str) -> Result<(), Json<Value>>{
    if exist(&path)?{
        Ok(())
    }else {
        match fs::create_dir_all(path).await {
            Ok(_) => Ok(()),
            Err(e) => Err( code::sys_(super::error::msg(e)))
        }
    }
}
pub async fn create_file(path:&str) -> Result<File, Json<Value>>{
    match fs::File::create(path).await {
        Ok(f) => Ok(f),
        Err(e) => Err( code::sys_(super::error::msg(e)))
    }
}

pub async fn open_file(path:&str) -> Result<File, Json<Value>>{
    match fs::File::open(path).await {
        Ok(f) => Ok(f),
        Err(e) => Err( code::sys_(super::error::msg(e)))
    }
}
// 读取文件，文件存不存在报错
pub async fn open_file_read_to_str(path:&str) -> Result<String, Json<Value>>{
    let mut buffer = String::new();
    let mut file = open_file(&path).await?;
    match file.read_to_string(&mut buffer).await {
        Ok(_) => Ok(buffer),
        Err(e) => { Err(code::sys_(e.to_string())) }
    }
}
// 读取文件，文件存不存在返回空
pub async fn open_file_read_to_str_(path:&str) -> Result<String, Json<Value>>{
    if exist(path)? {
        open_file_read_to_str(&path).await
    }else{
        Ok("".to_owned())
    }
}
// 读取文件，文件存不存在返回空
pub async fn open_file_read_to_str_send(path:&str) -> Result<Json<Value>, Json<Value>>{
    if exist(path)? {
        code::data(json!(open_file_read_to_str(&path).await?))
    }else{
        code::data(json!(""))
    }
}
// 打开文件时清空
pub async fn open_file_clear(path:&str) -> Result<File, Json<Value>>{
    match fs::File::options().write(true).read(true).truncate(true).open(&path).await {
        Ok(f) => Ok(f),
        Err(e) => Err( code::sys_(super::error::msg(e)))
    }
}
// 能追加文件模式打开文件
pub async fn open_file_append(path:&str) -> Result<File, Json<Value>>{
    match fs::File::options().write(true).read(true).append(true).open(&path).await {
        Ok(f) => Ok(f),
        Err(e) => Err( code::sys_(super::error::msg(e)))
    }
}
// 以追加模式打开文件并写入
pub async fn open_file_append_write_all(path:&str, content:&str) -> Result<Json<Value>, Json<Value>>{
    if content.is_empty() {
        return code::err(format!("【{}】数据为空，不更新", path));
    }
    let mut file = open_file_append(&path).await?;
    if let Err(e) = file.write_all(content.as_bytes()).await {
        return code::err(format!("{} 写入错误: {}", path, &e.to_string()))
    }
    if let Err(e) = file.flush().await {
        return code::err(format!("{} flush 错误: {}", path, &e.to_string()))
    }
    code::ok()
}
// 创建文件并写入
pub async fn create_file_write_all(path:&str, content:&str) -> Result<Json<Value>, Json<Value>>{
    if content.is_empty() {
        return code::err(format!("【{}】数据为空，不更新", path));
    }
    let mut file = create_file(path).await?;
    if let Err(e) = file.write_all(content.as_bytes()).await {
        return code::err(format!("{} 写入错误: {}", path, &e.to_string()))
    }
    if let Err(e) = file.flush().await {
        return code::err(format!("{} flush 错误: {}", path, &e.to_string()))
    }
    code::ok()
}
pub async fn create_file_write_all_bytes(path:&str, bytes:&Vec<u8>) -> Result<Json<Value>, Json<Value>>{
    if bytes.is_empty() {
        return code::err(format!("【{}】数据为空，不更新", path));
    }
    let mut file = create_file(path).await?;
    if let Err(e) = file.write_all(bytes).await {
        return code::err(format!("{} 写入错误: {}", path, &e.to_string()))
    }
    if let Err(e) = file.flush().await {
        return code::err(format!("{} flush 错误: {}", path, &e.to_string()))
    }
    code::ok()
}
// 清空文件并写入
pub async fn open_file_clear_write_all(path:&str, content:&str) -> Result<Json<Value>, Json<Value>>{
    let t = open_file_read_to_str_(&path).await?;
    if t.is_empty() {
        return code::err(format!("【{}】数据为空，不更新", path));
    }
    if t.eq(&content) {
        return code::err(format!("【{}】数据未发生变化，不更新", path));
    }
    let mut file = open_file_clear(&path).await?;
    if let Err(e) = file.write_all(content.as_bytes()).await {
        return code::err(format!("{} 写入错误: {}", path, &e.to_string()))
    }
    if let Err(e) = file.flush().await {
        return code::err(format!("{} flush 错误: {}", path, &e.to_string()))
    }
    code::ok()
}
// 清空文件并写入，不允许文件不存在
pub async fn open_file_clear_write_all_not_null(path:&str, content:&str) -> Result<Json<Value>, Json<Value>>{
    if exist(&path)? {
        open_file_clear_write_all(path, content).await
    }else{
        return code::err(format!("表文件【{}】不存在，不允许操作", &path))
    }
}
// 文件存在时写入，不存在时创建并写入
pub async fn write_all_flie(path:&str, content:&str) -> Result<Json<Value>, Json<Value>>{
    if exist(&path)? {
        open_file_clear_write_all(&path, &content).await
    }else{
        create_file_write_all(&path, &content).await
    }
}